{
  "name": "Review Responder AI Agent - Template",
  "nodes": [
    {
      "parameters": {
        "pollTimes": {
          "item": [
            {
              "mode": "everyMinute"
            }
          ]
        },
        "account": {
          "__rl": true,
          "value": "accounts/114720031070513437145",
          "mode": "list",
          "cachedResultName": "Will Toro"
        },
        "location": {
          "__rl": true,
          "value": "locations/16002758370357038151",
          "mode": "list",
          "cachedResultName": "locations/16002758370357038151"
        }
      },
      "type": "n8n-nodes-base.googleBusinessProfileTrigger",
      "typeVersion": 1,
      "position": [
        0,
        128
      ],
      "id": "08df1fb7-482a-4c1c-8cc7-01d4ea405a7a",
      "name": "Google Business Profile Trigger",
      "credentials": {
        "googleBusinessProfileOAuth2Api": {
          "id": "bAebu7y46WbolCdk",
          "name": "Google Business Profile account"
        }
      }
    },
    {
      "parameters": {
        "promptType": "define",
        "text": "=You are an expert customer engagement assistant for {{ $json.company_name }}, a trusted appliance repair company in {{ $json.city_state }}. Your job is to write short, friendly, natural-sounding responses to Google reviews. Keep them conversational and authentic, as if you’re talking to the customer over coffee — not corporate or robotic.\n\nUse these inputs:\n- Reviewer Name: {{ $('Pull Short Name').item.json.shortname }}\n- Star Rating: {{ $('Pull Short Name').item.json.starRating }}\n- Review Text: {{ $('Pull Short Name').item.json.comment }}\n\nWrite a unique response that:\n1. Feels personal and grateful, mention the reviewer by name if available.\n2. Acknowledges what the customer said (positive or negative).\n3. Sounds human, use small imperfections in tone or sentence structure to make it feel real.\n4. Stays under 10 sentences as needed.\n5. Ends with this signature:\n\n**Best regards,  \nThe Appliance GrandMasters Team**\n\nTone guidelines:\n- For 5-star reviews: Be upbeat, warm, and appreciative.\n- For 4-star reviews: Thank them, and politely show care to improve (“We’d love to know how we can make your next visit a 5-star one!”).\n- For 3 stars or less: Stay empathetic, calm, and caring. Acknowledge their experience and invite them to contact us to make it right. Use the comment from the customer to expand in the response. Apologize and acknowledge using context from the comments.The main purpose of responding is to gain back the customer's trust and show publicly how we stand behind our service.\n- Never sound defensive or copy-paste.\n- Do not sound like AI and do not use - or long hyphens —\n\nOutput format (JSON):\n{\n  \"reviewer_name\": \"...\",\n  \"rating\": \"...\",\n  \"review_text\": \"...\",\n  \"response\": \"...\"\n}\n",
        "options": {}
      },
      "type": "@n8n/n8n-nodes-langchain.agent",
      "typeVersion": 3,
      "position": [
        672,
        128
      ],
      "id": "e7ad4ad7-1db9-4999-8a8e-2976a242a7b5",
      "name": "AI Agent"
    },
    {
      "parameters": {
        "rules": {
          "values": [
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 2
                },
                "conditions": [
                  {
                    "leftValue": "={{ $json.rating }}",
                    "rightValue": "FIVE",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "id": "53940fa9-4f90-4b4c-a576-d34b498cedbf"
                  }
                ],
                "combinator": "and"
              },
              "renameOutput": true,
              "outputKey": "5"
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 2
                },
                "conditions": [
                  {
                    "id": "b3f615e2-b2d1-4c10-a3da-4518b7e6ae6c",
                    "leftValue": "={{ $json.rating }}",
                    "rightValue": "FOUR",
                    "operator": {
                      "type": "string",
                      "operation": "equals",
                      "name": "filter.operator.equals"
                    }
                  }
                ],
                "combinator": "and"
              },
              "renameOutput": true,
              "outputKey": "4"
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 2
                },
                "conditions": [
                  {
                    "id": "76fef6af-faf5-48de-8dcc-d9b5a66d26d6",
                    "leftValue": "={{ $json.rating }}",
                    "rightValue": "THREE",
                    "operator": {
                      "type": "string",
                      "operation": "equals",
                      "name": "filter.operator.equals"
                    }
                  }
                ],
                "combinator": "and"
              },
              "renameOutput": true,
              "outputKey": "3"
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 2
                },
                "conditions": [
                  {
                    "id": "ed28274f-4d97-4a99-af33-f5f12478df8f",
                    "leftValue": "={{ $json.rating }}",
                    "rightValue": "TWO",
                    "operator": {
                      "type": "string",
                      "operation": "equals",
                      "name": "filter.operator.equals"
                    }
                  }
                ],
                "combinator": "and"
              },
              "renameOutput": true,
              "outputKey": "2"
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 2
                },
                "conditions": [
                  {
                    "id": "a08db930-5166-4273-85e1-463f24d97f48",
                    "leftValue": "={{ $json.rating }}",
                    "rightValue": "ONE",
                    "operator": {
                      "type": "string",
                      "operation": "equals",
                      "name": "filter.operator.equals"
                    }
                  }
                ],
                "combinator": "and"
              },
              "renameOutput": true,
              "outputKey": "1"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.switch",
      "typeVersion": 3.3,
      "position": [
        1232,
        -32
      ],
      "id": "5b3019e6-19d6-49d2-9629-89078e079532",
      "name": "Switch"
    },
    {
      "parameters": {
        "model": {
          "__rl": true,
          "value": "gpt-3.5-turbo",
          "mode": "list",
          "cachedResultName": "gpt-3.5-turbo"
        },
        "options": {}
      },
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "typeVersion": 1.2,
      "position": [
        528,
        352
      ],
      "id": "675e0bc6-3632-42d7-b08e-810343317453",
      "name": "OpenAI Chat Model",
      "credentials": {
        "openAiApi": {
          "id": "9d01Yb8z3wRAj5tY",
          "name": "OpenAi account"
        }
      }
    },
    {
      "parameters": {
        "resource": "review",
        "operation": "reply",
        "account": {
          "__rl": true,
          "value": "accounts/114720031070513437145",
          "mode": "list",
          "cachedResultName": "Will Toro"
        },
        "location": {
          "__rl": true,
          "value": "locations/16002758370357038151",
          "mode": "list",
          "cachedResultName": "locations/16002758370357038151"
        },
        "review": {
          "__rl": true,
          "value": "={{ $('Google Business Profile Trigger').item.json.reviewId }}",
          "mode": "id"
        },
        "reply": "={{ $('Parse Output').item.json.response }}",
        "requestOptions": {}
      },
      "type": "n8n-nodes-base.googleBusinessProfile",
      "typeVersion": 1,
      "position": [
        1456,
        -32
      ],
      "id": "b68d4c1d-401c-47a4-9106-aa71c439519f",
      "name": "Reply to review",
      "credentials": {
        "googleBusinessProfileOAuth2Api": {
          "id": "bAebu7y46WbolCdk",
          "name": "Google Business Profile account"
        }
      }
    },
    {
      "parameters": {
        "sendTo": "gvlsc@appliancegm.com",
        "subject": "=Bad Review Response Draft - {{ $('Google Business Profile Trigger').item.json.reviewer.displayName }}  - {{ $('Google Business Profile Trigger').item.json.starRating }} Star Review",
        "message": "=<!DOCTYPE html>\n<html lang=\"en\" style=\"margin:0;padding:0;\">\n<head>\n  <meta charset=\"utf-8\">\n  <meta name=\"viewport\" content=\"width=device-width\">\n  <title>New Google Review – Action Needed</title>\n  <style>\n    /* Clients that respect <style> will use this; everything important is also inlined */\n    @media (max-width:600px){\n      .container{width:100% !important; padding:16px !important;}\n    }\n  </style>\n</head>\n<body style=\"margin:0;padding:0;background:#f6f7f9;font-family:Arial,Helvetica,sans-serif;color:#1f2937;\">\n  <table role=\"presentation\" width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" style=\"background:#f6f7f9;\">\n    <tr>\n      <td align=\"center\" style=\"padding:24px;\">\n        <table role=\"presentation\" class=\"container\" width=\"600\" cellpadding=\"0\" cellspacing=\"0\" style=\"width:600px;max-width:100%;background:#ffffff;border-radius:10px;overflow:hidden;box-shadow:0 1px 3px rgba(0,0,0,0.06);\">\n          <!-- Header -->\n          <tr>\n            <td style=\"background:#0b74de;color:#ffffff;padding:20px 24px;\">\n              <h1 style=\"margin:0;font-size:18px;line-height:1.3;\">New Google Review – Action Needed</h1>\n              <p style=\"margin:6px 0 0;font-size:13px;opacity:.9;\">Please review and send a response to the customer.</p>\n            </td>\n          </tr>\n\n          <!-- Intro -->\n          <tr>\n            <td style=\"padding:20px 24px;\">\n              <p style=\"margin:0 0 12px;font-size:14px;\">Hi team,</p>\n              <p style=\"margin:0 0 16px;font-size:14px;\">\n                We just received a <strong>{{ $json.rating }}</strong> star review that requires a response.\n              </p>\n            </td>\n          </tr>\n\n          <!-- Review Info -->\n          <tr>\n            <td style=\"padding:0 24px 20px;\">\n              <table role=\"presentation\" width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" style=\"border:1px solid #e5e7eb;border-radius:8px;\">\n                <tr>\n                  <td style=\"padding:14px 16px;background:#f9fafb;border-bottom:1px solid #e5e7eb;\">\n                    <strong style=\"font-size:14px;\">Review Info</strong>\n                  </td>\n                </tr>\n                <tr>\n                  <td style=\"padding:14px 16px;font-size:14px;line-height:1.6;\">\n                    <div><strong>Name:</strong> {{ $('Google Business Profile Trigger').item.json.reviewer.displayName }}</div>\n                    <div><strong>Rating:</strong> {{ $('Google Business Profile Trigger').item.json.starRating }}</div>\n                    <div style=\"margin-top:8px;\"><strong>Review Text:</strong></div>\n                    <div style=\"margin-top:6px;padding:12px;border:1px solid #e5e7eb;border-radius:6px;background:#fcfcfd;white-space:pre-wrap;\">\n                     {{ $('Google Business Profile Trigger').item.json.comment }}\n                    </div>\n                  </td>\n                </tr>\n              </table>\n            </td>\n          </tr>\n\n          <!-- Draft Response -->\n          <tr>\n            <td style=\"padding:0 24px 20px;\">\n              <table role=\"presentation\" width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" style=\"border:1px solid #e5e7eb;border-radius:8px;\">\n                <tr>\n                  <td style=\"padding:14px 16px;background:#f9fafb;border-bottom:1px solid #e5e7eb;\">\n                    <strong style=\"font-size:14px;\">Draft Response (copy &amp; paste)</strong>\n                  </td>\n                </tr>\n                <tr>\n                  <td style=\"padding:14px 16px;font-size:14px;line-height:1.6;\">\n                    <div style=\"padding:12px;border:1px dashed #cbd5e1;border-radius:6px;background:#ffffff;white-space:pre-wrap;\">\n                      {{ $json.response }}\n                    </div>\n                  </td>\n                </tr>\n              </table>\n            </td>\n          </tr>\n\n          <!-- Actions -->\n          <tr>\n            <td style=\"padding:0 24px 24px;\">\n              <table role=\"presentation\" cellpadding=\"0\" cellspacing=\"0\">\n                <tr>\n                  <td>\n                    <a href=\"https://share.google/9nFPuT9v7GoXFgduL\" style=\"display:inline-block;background:#0b74de;color:#ffffff;text-decoration:none;padding:10px 14px;border-radius:8px;font-size:14px;\">\n                      Open Review\n                    </a>\n                  </td>\n                  <td width=\"12\"></td>\n                  <td>\n                    <a href=\"mailto:\"\"?subject=Review%20Response%20Edit&body={{ encodeURIComponent($json.response || '') }}\" style=\"display:inline-block;background:#111827;color:#ffffff;text-decoration:none;padding:10px 14px;border-radius:8px;font-size:14px;\">\n                      Send Edit via Email\n                    </a>\n                  </td>\n                </tr>\n              </table>\n\n              <p style=\"margin:14px 0 0;font-size:12px;color:#6b7280;\">\n                Tip: If the rating is 3★ or below, consider a more empathetic tone and invite the customer to continue the conversation offline.\n              </p>\n            </td>\n          </tr>\n\n          <!-- Footer -->\n          <tr>\n            <td style=\"padding:16px 24px;background:#f9fafb;border-top:1px solid #e5e7eb;\">\n              <p style=\"margin:0;font-size:12px;color:#6b7280;\">\n                Appliance GrandMasters • Greenville, SC • <a href=\"https://appliancegm.com\" style=\"color:#0b74de;text-decoration:none;\">appliancegm.com</a>\n              </p>\n            </td>\n          </tr>\n\n        </table>\n      </td>\n    </tr>\n  </table>\n</body>\n</html>\n",
        "options": {
          "senderName": "Jarvis AGM - Review Agent"
        }
      },
      "type": "n8n-nodes-base.gmail",
      "typeVersion": 2.1,
      "position": [
        1472,
        224
      ],
      "id": "189c5fb4-65b9-485d-b854-bd7ac03c9882",
      "name": "Send a message",
      "webhookId": "c274922e-a978-4dfc-976b-0288ed2d9aac",
      "credentials": {
        "gmailOAuth2": {
          "id": "RaTsrmolHvJbOjlm",
          "name": "Gmail GVL"
        }
      }
    },
    {
      "parameters": {
        "promptType": "define",
        "text": "=You are a social media content writer for {{ $('Company Info').item.json.company_name }}, an appliance repair company in {{ $('Company Info').item.json.city_state }}.\n\nWrite a short, friendly caption for Facebook and Instagram based on the following review:\n\nReviewer: {{ $('Pull Short Name').item.json.shortname }}\n\nReview: {{ $('Google Business Profile Trigger').item.json.comment }}\n\nGuidelines:\n- Keep it under 60 words.\n- Focus on gratitude and quality service.\n- Only use the Customer's first name. If last name is provided just use the initial. For example Will T.\n- End with a light call-to-action like “Thank you for trusting us!”.\n- Use these hashtags always:\n  #ApplianceGrandMasters #ApplianceRepair #ApplianceRepairService #GreenvilleSC #AshevilleNC\n\nReturn as JSON:\n{\n  \"caption\": \"...\",\n  \"hashtags\": [\"...\", \"...\", \"...\", \"...\", \"...\"],\n  \"reviewerfirstname\": \"...\",\n\n}\n",
        "options": {}
      },
      "type": "@n8n/n8n-nodes-langchain.agent",
      "typeVersion": 3,
      "position": [
        1744,
        -32
      ],
      "id": "8747a9e0-b50e-45f2-b53a-1c058b9b9c02",
      "name": "AI Agent1"
    },
    {
      "parameters": {
        "model": {
          "__rl": true,
          "value": "gpt-4-turbo",
          "mode": "list",
          "cachedResultName": "gpt-4-turbo"
        },
        "options": {}
      },
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "typeVersion": 1.2,
      "position": [
        1760,
        208
      ],
      "id": "8c46de6f-7883-4bfe-a251-b5505e349905",
      "name": "OpenAI Chat Model1",
      "credentials": {
        "openAiApi": {
          "id": "9d01Yb8z3wRAj5tY",
          "name": "OpenAi account"
        }
      }
    },
    {
      "parameters": {
        "html": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n<meta charset=\"UTF-8\" />\n\n<style>\n  body {\n    width: 1080px;\n    height: auto;\n    margin: 0;\n    padding: 0;\n    background: #0C223F;\n    font-family: Arial, sans-serif;\n    color: #ffffff;\n  }\n\n  /* Header */\n  .header-container {\n    padding: 70px 70px 40px 70px;\n  }\n\n  .title-line1 {\n    font-size: 80px;\n    font-weight: 700;\n    color: #FFB848;\n  }\n\n  .title-line2 {\n    font-size: 95px;\n    font-weight: 800;\n    margin-top: -10px;\n  }\n\n  /* Review Card */\n  .card {\n    width: 86%;\n    margin: 0 auto;\n    background: #ffffff;\n    border-radius: 35px;\n    padding: 60px;\n    color: #0C223F;\n    box-shadow: 0 8px 25px rgba(0,0,0,0.25);\n    position: relative;\n  }\n\n  .reviewer {\n    font-size: 52px;\n    font-weight: 700;\n    margin-bottom: 5px;\n  }\n\n  .stars {\n    font-size: 42px;\n    color: #FFB848;\n    margin-bottom: 28px;\n  }\n\n  /* Auto-scaling review text */\n  .review-text {\n    font-size: 36px;\n    line-height: 1.45;\n    font-weight: 400;\n    display: block;\n  }\n\n  /* Shrink text if long */\n  .review-text.long {\n    font-size: 30px;\n  }\n\n  .review-text.very-long {\n    font-size: 26px;\n  }\n\n  /* Floating logo */\n  .logo {\n    position: absolute;\n    right: -40px;\n    top: -40px;\n    width: 200px;\n    height: 200px;\n    border-radius: 50%;\n    background: #ffffff;\n    padding: 15px;\n    box-shadow: 0 4px 20px rgba(0,0,0,0.25);\n    object-fit: contain;\n  }\n\n  /* Footer Section */\n  .footer {\n    margin-top: 60px;\n    width: 100%;\n    height: auto;\n    background: #C8102E;\n    text-align: center;\n    padding: 60px 0 80px 0;\n    color: white;\n  }\n\n  .brand {\n    font-size: 55px;\n    font-weight: 700;\n  }\n\n  .address {\n    margin-top: 10px;\n    font-size: 32px;\n  }\n\n  .footer-stars {\n    margin-top: 20px;\n    font-size: 40px;\n    color: #FFB848;\n    letter-spacing: 6px;\n  }\n\n  .phone-btn {\n    margin-top: 35px;\n    font-size: 44px;\n    font-weight: bold;\n    background: #0C223F;\n    padding: 20px 60px;\n    border-radius: 50px;\n    display: inline-block;\n    color: white;\n  }\n</style>\n\n</head>\n<body>\n\n<div class=\"header-container\">\n  <div class=\"title-line1\">Our Customer</div>\n  <div class=\"title-line2\">REVIEWS</div>\n</div>\n\n<!-- REVIEW CARD -->\n<div class=\"card\">\n\n  <div class=\"reviewer\">{{ $('Parse Output1').item.json.reviewerfirstname }}</div>\n\n  <div class=\"stars\">★★★★★</div>\n\n  <!-- Dynamically assign class based on review length -->\n  <div class=\"review-text {{review_text_length_class}}\">\n    “ {{ $('Google Business Profile Trigger').item.json.comment }}”\n  </div>\n\n  <img class=\"logo\" src=\"https://mcusercontent.com/c3419d657e8196e2da76f6b90/images/cd6e753f-9130-401c-deb2-0264bf4b0b9c.png\">\n</div>\n\n<!-- FOOTER -->\n<div class=\"footer\">\n  <div class=\"brand\">Appliance GrandMasters</div>\n  <div class=\"address\">2421 New Easley Hwy, Greenville, SC</div>\n  <div class=\"footer-stars\">★★★★★</div>\n  <div class=\"phone-btn\">(864) 513-1828</div>\n</div>\n\n</body>\n</html>\n"
      },
      "type": "n8n-nodes-base.html",
      "typeVersion": 1.2,
      "position": [
        2304,
        -608
      ],
      "id": "c6d10778-a826-41c5-b965-3eeff150185d",
      "name": "HTML"
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://hcti.io/v1/image",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "authorization",
              "value": "Basic MDFLOVowVjlURTkzN1FUSEdXU0ZGOUFCTTggOjAxOWE3ZTBkLWE3NGUtN2NlNC1hNWE5LWFhZmE0ZjdlMDhkNQ=="
            }
          ]
        },
        "sendBody": true,
        "contentType": "form-urlencoded",
        "bodyParameters": {
          "parameters": [
            {
              "name": "html",
              "value": "={{ $json.html }}"
            },
            {
              "name": "css",
              "value": ".ping { padding: 20px; font-family: 'sans-serif'; }"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.3,
      "position": [
        2528,
        -608
      ],
      "id": "e301b19e-caad-4ae7-a717-bc896314af44",
      "name": "HTTP Request1"
    },
    {
      "parameters": {
        "url": "={{ $json.url }}",
        "options": {
          "response": {
            "response": {
              "responseFormat": "file"
            }
          }
        }
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.3,
      "position": [
        2752,
        -608
      ],
      "id": "9aab15f4-6d1c-4a79-8154-342d50c987dc",
      "name": "HTTP Request2"
    },
    {
      "parameters": {
        "operation": "crop",
        "width": 1080,
        "height": 1200,
        "options": {}
      },
      "type": "n8n-nodes-base.editImage",
      "typeVersion": 1,
      "position": [
        2976,
        -608
      ],
      "id": "2a6e6631-c578-4a51-84c8-07adb25bab29",
      "name": "Edit Image"
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 2
          },
          "conditions": [
            {
              "id": "e4dd5628-d637-408b-9c2d-57294275a8c0",
              "leftValue": "={{ $json.data.approved }}",
              "rightValue": "true",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        3280,
        -32
      ],
      "id": "985bbf39-f5f8-4a39-b79a-14cd37064be1",
      "name": "If"
    },
    {
      "parameters": {
        "jsCode": "// Try to read the name field safely\nconst fullName = $input.first().json.reviewer.displayName || \"\";\n\n// If the name looks like a Google review resource ID, return empty\nif (fullName.includes(\"accounts/\") || fullName.includes(\"/reviews/\")) {\n  return [{\n    json: {\n      ...$json,\n      shortname: \"\"\n    }\n  }];\n}\n\nlet shortName = \"\";\n\ntry {\n  const parts = fullName.trim().split(/\\s+/);\n\n  // Must have at least 2 words to abbreviate\n  if (parts.length >= 2) {\n    const first = parts[0];\n    const last = parts[parts.length - 1]; // supports middle names\n    shortName = `${first} ${last[0]}.`;\n  } else {\n    // One-word name — return as-is\n    shortName = parts[0] || \"\";\n  }\n\n} catch (e) {\n  shortName = \"\";\n}\n\nreturn [{\n  json: {\n    ...$json,\n    shortname: shortName\n  }\n}];\n"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        224,
        128
      ],
      "id": "e76f3828-8138-4cec-b884-9ca60a22be5d",
      "name": "Pull Short Name"
    },
    {
      "parameters": {
        "jsCode": "// Get the AI Agent output (stringified JSON)\nconst rawOutput = $json.output || \"\";\n\n// Safe JSON parsing helper\nfunction safeParseJSON(str) {\n  try {\n    // Remove code block formatting (```json ... ```) if present\n    const cleanStr = str.replace(/```json|```/g, \"\").trim();\n    return JSON.parse(cleanStr);\n  } catch (error) {\n    return { error: \"Invalid JSON format\", raw: str };\n  }\n}\n\n// Parse the output\nconst parsed = safeParseJSON(rawOutput);\n\n// Return parsed result so it can be used in next nodes\nreturn [\n  {\n    json: parsed\n  }\n];\n"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1008,
        128
      ],
      "id": "5d207a01-409a-4985-81d0-aa478c49fde9",
      "name": "Parse Output"
    },
    {
      "parameters": {
        "jsCode": "// Get the raw string from the AI agent output\nconst raw = $json.output;\n\n// Try to parse it as JSON\nlet parsed;\ntry {\n  parsed = JSON.parse(raw);\n} catch (e) {\n  throw new Error(\"Failed to parse AI output: \" + e.message + \"\\nRaw: \" + raw);\n}\n\n// Return the parsed object\nreturn [\n  {\n    json: {\n      caption: parsed.caption || \"\",\n      hashtags: parsed.hashtags || [],\n      reviewerfirstname: parsed.reviewerfirstname || \"\",\n      raw: raw\n    }\n  }\n];\n"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        2032,
        -32
      ],
      "id": "38c2872f-6d3b-4e60-9b17-c99e7f6d77fb",
      "name": "Parse Output1"
    },
    {
      "parameters": {
        "jsCode": "const text = $json.review_text || \"\";\nconst len = text.length;\n\nlet cls = \"\";\n\nif (len > 400) {\n  cls = \"very-long\";\n} else if (len > 250) {\n  cls = \"long\";\n}\n\nreturn {\n  reviewer_name: $json.reviewer_name,\n  review_text: text,\n  review_text_length_class: cls\n};\n"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        2208,
        -32
      ],
      "id": "2b3f0a17-ec1d-4b73-b2c7-6319630f831a",
      "name": "Classify Length"
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://rest.apitemplate.io/v2/create-image",
        "sendQuery": true,
        "queryParameters": {
          "parameters": [
            {
              "name": "template_id",
              "value": "template ID number"
            }
          ]
        },
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "X-API-KEY",
              "value": "YOUR_API_KEY"
            }
          ]
        },
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={\n    \"overrides\": [\n        {\n            \"name\": \"background-color\",\n            \"stroke\": \"grey\",\n            \"backgroundColor\": \"#0C223F\"\n        },\n        {\n            \"name\": \"rect_1\",\n            \"stroke\": \"grey\",\n            \"backgroundColor\": \"#C8102E\"\n        },\n        {\n            \"name\": \"text_1\",\n            \"text\": \"Our Customer\",\n            \"textBackgroundColor\": \"rgba(0, 0, 0, 0)\",\n            \"color\": \"#FFB848\"\n        },\n        {\n            \"name\": \"text_2\",\n            \"text\": \"Reviews\",\n            \"textBackgroundColor\": \"rgba(0, 0, 0, 0)\",\n            \"color\": \"#FFFFFF\"\n        },\n        {\n            \"name\": \"rect_2\",\n            \"stroke\": \"#FFFFFF\",\n            \"backgroundColor\": \"#0C223F\"\n        },\n        {\n            \"name\": \"text_3\",\n            \"text\": \"{{ $('Company Info').item.json.company_name }}\",\n            \"textBackgroundColor\": \"rgba(0, 0, 0, 0)\",\n            \"color\": \"#FFFFFF\"\n        },\n        {\n            \"name\": \"text_3_1\",\n            \"text\": \"(864) 513-1828\",\n            \"textBackgroundColor\": \"rgba(0, 0, 0, 0)\",\n            \"color\": \"#FFFFFF\"\n        },\n        {\n            \"name\": \"rating_1\",\n            \"backgroundColor\": \"\",\n            \"percent\": 100,\n            \"color\": \"#FBE34C\"\n        },\n        {\n            \"name\": \"rect_3\",\n            \"stroke\": \"grey\",\n            \"backgroundColor\": \"#FFFFFF\"\n        },\n        {\n            \"name\": \"circle-image_1\",\n            \"stroke\": \"#822222\",\n            \"src\": \"https://apitemplateio-user.s3-ap-southeast-1.amazonaws.com/42996/57231/b50f26fe-f059-4f64-bc4f-c06dad3a7f64.png\"\n        },\n        {\n            \"name\": \"text_review\",\n            \"text\": \"\\n {{ $('Google Business Profile Trigger').item.json.comment }} \\n\",\n            \"textBackgroundColor\": \"rgba(0, 0, 0, 0)\",\n            \"color\": \"#000000\",\n            \"rectFillColor\": \"\"\n        },\n        {\n            \"name\": \"text_reviewer\",\n            \"text\": \"{{ $('Pull Short Name').item.json.shortname }}\",\n            \"textBackgroundColor\": \"rgba(0, 0, 0, 0)\",\n            \"color\": \"#FFFFFF\"\n        }\n    ]\n}",
        "options": {}
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.3,
      "position": [
        2448,
        -32
      ],
      "id": "182ec1fc-00c4-45cc-8c71-f0c05725b14e",
      "name": "HTTP - Create Image"
    },
    {
      "parameters": {
        "url": "={{ $json.download_url_png }}",
        "options": {
          "response": {
            "response": {
              "responseFormat": "file"
            }
          }
        }
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.3,
      "position": [
        2640,
        -32
      ],
      "id": "34ebb0ea-e66a-4fc0-a11d-139febc052b0",
      "name": "Download Image"
    },
    {
      "parameters": {
        "operation": "sendPhoto",
        "chatId": "YOUR_CHAT_ID",
        "binaryData": true,
        "additionalFields": {
          "caption": "={{ $('Parse Output1').item.json.caption }}"
        }
      },
      "type": "n8n-nodes-base.telegram",
      "typeVersion": 1.2,
      "position": [
        2816,
        -32
      ],
      "id": "4611a894-fcdd-492e-8785-4d745c6a9d0d",
      "name": "Send Image to Human",
      "webhookId": "d01a139c-8fd8-4b5f-964c-75be71b9a754",
      "credentials": {
        "telegramApi": {
          "id": "lhfUA9iIhk4O3FGa",
          "name": "Telegram account"
        }
      }
    },
    {
      "parameters": {
        "operation": "sendAndWait",
        "chatId": "YOUR_CHAT_ID",
        "message": "Do we post this to FB?",
        "approvalOptions": {
          "values": {
            "approvalType": "double"
          }
        },
        "options": {
          "appendAttribution": false
        }
      },
      "type": "n8n-nodes-base.telegram",
      "typeVersion": 1.2,
      "position": [
        3056,
        -32
      ],
      "id": "f6b4b100-aa79-41ab-889d-0bc1f8e20f82",
      "name": "Wait for Approval",
      "webhookId": "11205e1b-ea74-47e8-8268-3378edc92160",
      "credentials": {
        "telegramApi": {
          "id": "lhfUA9iIhk4O3FGa",
          "name": "Telegram account"
        }
      }
    },
    {
      "parameters": {
        "httpRequestMethod": "POST",
        "graphApiVersion": "v23.0",
        "node": "me",
        "edge": "photos",
        "options": {
          "queryParameters": {
            "parameter": [
              {
                "name": "message",
                "value": "={{ $('Parse Output1').item.json.caption }}"
              },
              {
                "name": "url",
                "value": "={{ $('HTTP - Create Image').item.json.download_url }}"
              }
            ]
          }
        }
      },
      "type": "n8n-nodes-base.facebookGraphApi",
      "typeVersion": 1,
      "position": [
        3520,
        -192
      ],
      "id": "f8229d34-50bd-4160-93ae-4eeed462b154",
      "name": "Facebook Graph API",
      "credentials": {
        "facebookGraphApi": {
          "id": "pzB2MPbiun8gib7D",
          "name": "Facebook Business Graph account"
        }
      }
    },
    {
      "parameters": {
        "content": "## Step 1\n** Connect Google Business Profile (Trigger)**\n\nThis automation starts when a new Google review is posted.\n\n- Open the Google Business Profile Trigger node\n\n- Click Create New Credential\n\n- Authenticate with the Google account that owns or manages the business listing\n\n- Select the correct Location / Business Profile\n\n✅ This node controls when the automation runs.\n\nThe account setup might be tricky, for assistance visit:\nhttps://docs.n8n.io/integrations/builtin/credentials/google/oauth-single-service/",
        "height": 576,
        "width": 464
      },
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -288,
        -272
      ],
      "typeVersion": 1,
      "id": "9ac0f086-185d-438d-adf9-f7e641f7ecda",
      "name": "Sticky Note"
    },
    {
      "parameters": {
        "content": "## Additional Help\nHere is a youtube video on how to configure it:\nhttps://www.youtube.com/watch?v=8tX8urfjG8I",
        "height": 224,
        "width": 464
      },
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -288,
        320
      ],
      "typeVersion": 1,
      "id": "55ae82dc-9d86-445c-81a0-c491d7496984",
      "name": "Sticky Note1"
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "4d4f517b-7fd5-45d5-a0b6-1face04ad1fa",
              "name": "company_name",
              "value": "Company Name",
              "type": "string"
            },
            {
              "id": "aefd3e6a-d319-497d-a694-a93d6ee5d455",
              "name": "city_state",
              "value": "Greenville, SC",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        432,
        128
      ],
      "id": "23dc50ac-f5c3-4850-a46a-11dcaa5f458e",
      "name": "Company Info"
    },
    {
      "parameters": {
        "content": "## End of Stage 1\n**If not social post is needed you can delete after this nodes**",
        "height": 560,
        "color": 3
      },
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1424,
        -144
      ],
      "typeVersion": 1,
      "id": "d6f0a1ea-fa41-4c53-8c9f-a59462a64fb5",
      "name": "Sticky Note2"
    },
    {
      "parameters": {
        "content": "## Stage 2\n**Social Posting**",
        "height": 832,
        "width": 1984,
        "color": 6
      },
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1696,
        -320
      ],
      "typeVersion": 1,
      "id": "8b1a307a-d558-4fb3-bc5b-e5b8316263cf",
      "name": "Sticky Note3"
    }
  ],
  "pinData": {
    "Google Business Profile Trigger": [
      {
        "json": {
          "reviewId": "AbFvOqkjrDcgUHCQdYnrbujnLpv3JD-Uv15C6bCA7g071Dpe4NwQjrejqWQm4CwWYMy8syxHOaoJlA",
          "reviewer": {
            "profilePhotoUrl": "https://lh3.googleusercontent.com/a-/ALV-UjXE3mmvJ0AAmZSceqPDutZc9bQtJwXGQAfzHFa5yqA6LVcFmsBv5g=s120-c-rp-mo-ba4-br100",
            "displayName": "Deborah McGowan"
          },
          "starRating": "FIVE",
          "comment": "Hugh was very prompt and courteous. He ensured that everything was safe before he started. Allowed me to clean behind fridge after he completed his work. Thank you.",
          "createTime": "2025-11-27T17:42:48.683019Z",
          "updateTime": "2025-11-27T17:42:48.683019Z",
          "name": "accounts/114720031070513437145/locations/16002758370357038151/reviews/AbFvOqkjrDcgUHCQdYnrbujnLpv3JD-Uv15C6bCA7g071Dpe4NwQjrejqWQm4CwWYMy8syxHOaoJlA"
        }
      }
    ]
  },
  "connections": {
    "Google Business Profile Trigger": {
      "main": [
        [
          {
            "node": "Pull Short Name",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "AI Agent": {
      "main": [
        [
          {
            "node": "Parse Output",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Switch": {
      "main": [
        [
          {
            "node": "Reply to review",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Reply to review",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Send a message",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Send a message",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Send a message",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "AI Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Reply to review": {
      "main": [
        [
          {
            "node": "AI Agent1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI Chat Model1": {
      "ai_languageModel": [
        [
          {
            "node": "AI Agent1",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "AI Agent1": {
      "main": [
        [
          {
            "node": "Parse Output1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "HTML": {
      "main": [
        [
          {
            "node": "HTTP Request1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "HTTP Request1": {
      "main": [
        [
          {
            "node": "HTTP Request2",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "HTTP Request2": {
      "main": [
        [
          {
            "node": "Edit Image",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Edit Image": {
      "main": [
        []
      ]
    },
    "If": {
      "main": [
        [
          {
            "node": "Facebook Graph API",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Pull Short Name": {
      "main": [
        [
          {
            "node": "Company Info",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse Output": {
      "main": [
        [
          {
            "node": "Switch",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse Output1": {
      "main": [
        [
          {
            "node": "Classify Length",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Classify Length": {
      "main": [
        [
          {
            "node": "HTTP - Create Image",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "HTTP - Create Image": {
      "main": [
        [
          {
            "node": "Download Image",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Download Image": {
      "main": [
        [
          {
            "node": "Send Image to Human",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send Image to Human": {
      "main": [
        [
          {
            "node": "Wait for Approval",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Wait for Approval": {
      "main": [
        [
          {
            "node": "If",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Company Info": {
      "main": [
        [
          {
            "node": "AI Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "active": false,
  "settings": {
    "executionOrder": "v1",
    "availableInMCP": false
  },
  "versionId": "aa477f6a-0f95-4eb5-a11f-60985f9e8a22",
  "meta": {
    "templateCredsSetupCompleted": true,
    "instanceId": "992f6b15ce9418f680548f917c88a9daa82a875a56a26e12ae36d126941f6f18"
  },
  "id": "pMRoGo9bMVxjZ9gQ",
  "tags": []
}